package com.softkey;

import com.ruoyi.common.core.exception.ServiceException;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

public class EncryptedVerification {

    public static void verify(String keyList) throws ClassNotFoundException {
        // TODO: Add initialization code here
        List<Class<?>> classList = new ArrayList<>();
        for (String listFile : keyList.split(",")) {
            Class<?> aClass = Class.forName("com.softkey."+listFile);
            classList.add(aClass);
        }

        int ret;

        /*String DevicePath;
        DevicePath = ytsoftkey.FindPort(0);*/
        boolean get_LastError = getMethodInvoke(classList, "get_LastError", x -> x != 0);
        if(get_LastError)
        {
            throw new ServiceException("未找到加密锁,请插入加密锁后，再进行操作。");
           /* System.out.println("未找到加密锁,请插入加密锁后，再进行操作。");
            return ;*/
        }

        boolean CheckKeyByFindort_2 = getMethodInvoke(classList, "CheckKeyByFindort_2", x -> x == 0);
        if (CheckKeyByFindort_2)
        {
            System.out.println("使用普通算法一来检查:找到指定的加密锁");
        }
        else
        {
//            System.out.println("使用普通算法一来检查:未能找到指定的加密锁"); return;
            throw new ServiceException("使用普通算法一来检查:未能找到指定的加密锁");
        }

//        ret = ytsoftkey.CheckKeyByEncstring();
        boolean CheckKeyByEncstring1 = getMethodInvoke(classList, "CheckKeyByEncstring", x -> x == 1);
        if (CheckKeyByEncstring1)
        {
            System.out.println( "你生成加密代码时没有设置该函数");
            return ;
        }
        boolean CheckKeyByEncstring2 = getMethodInvoke(classList, "CheckKeyByEncstring", x -> x == 0);
        if (CheckKeyByEncstring2)
        {
            System.out.println("使用增强算法一来检查:找到指定的加密锁");
        }
        else
        {
            throw new ServiceException("使用增强算法一来检查:未能找到指定的加密锁");
        }


//        ret = ytsoftkey.CheckKeyByEncstring_New();
        boolean CheckKeyByEncstring_New1 = getMethodInvoke(classList, "CheckKeyByEncstring_New", x -> x == 0);
        if (CheckKeyByEncstring_New1)
        {
            System.out.println("使用增强算法二来检查:找到指定的加密锁");
        }
        else
        {
            boolean CheckKeyByEncstring_New2 = getMethodInvoke(classList, "CheckKeyByEncstring_New", x -> x < 0);
            if (CheckKeyByEncstring_New2)
            {
                throw new ServiceException("使用增强算法二来检查:未能找到指定的加密锁");
            }
            else
            {
                boolean CheckKeyByEncstring_New3 = getMethodInvoke(classList, "CheckKeyByEncstring_New", x -> x == 2);
                if (CheckKeyByEncstring_New3)
                {
                    System.out.println("当前锁不支持这个功能。");
                    return;
                }
            }
        }
//        ret = ytsoftkey.CheckKeyByReadEprom();
        boolean CheckKeyByReadEprom1 = getMethodInvoke(classList, "CheckKeyByReadEprom", x -> x == 1);
        if (CheckKeyByReadEprom1)
        {
            System.out.println("你生成加密代码时没有设置该函数");
            return;
        }
        boolean CheckKeyByReadEprom2 = getMethodInvoke(classList, "CheckKeyByReadEprom", x -> x == 0);
        if (CheckKeyByReadEprom2)
        {
            System.out.println("使用读写储存器来检查:找到指定的加密锁");
        }
        else
        {
            System.out.println("使用读写储存器来检查:未能找到指定的加密锁"); return;
        }
    }


    public static boolean getMethodInvoke(List<Class<?>> classList, String methodName, Predicate<Integer> condition) {
        return classList.stream().anyMatch(aClass -> {
            //通过反射创建对象
            Object t = null;
            try {
                t = aClass.getDeclaredConstructor().newInstance();
                Object object = aClass.getMethod(methodName).invoke(t);
                return condition.test(Integer.parseInt(object.toString()));
            } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
                     NoSuchMethodException e) {
                throw new RuntimeException("反射调用失败: "+ aClass.getName());
            }
        });
    }
}
